package com.ruoyi.web.controller.ocr;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.utils.sign.Base64;
import com.ruoyi.domain.BankCardOcr;
import com.ruoyi.domain.BizLicenseOcr;
import com.ruoyi.domain.IdCardResult;
import com.ruoyi.framework.config.ServerConfig;
import com.ruoyi.service.BankCardOcrService;
import com.ruoyi.service.BizLicenseOcrService;
import com.ruoyi.service.IdCardResultService;
import com.ruoyi.web.controller.tool.OcrUtil;
import com.ruoyi.web.vo.*;
import com.tencentcloudapi.common.Credential;
import com.tencentcloudapi.ocr.v20181119.OcrClient;
import com.tencentcloudapi.ocr.v20181119.models.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 *
 *
 * @author WangFK
 * @since 2023-09-11 16:46:00
 */
@RestController
@Slf4j
@RequestMapping("/ocr")
@Anonymous
public class OcrController {
    /**
     * 服务对象
     */
    @Resource
    private BankCardOcrService bankCardOcrService;
    @Resource
    private BizLicenseOcrService bizLicenseOcrService;
    @Resource
    private IdCardResultService idCardResultService;
    @Resource
    private ServerConfig serverConfig;
    @Resource
    private com.ruoyi.web.controller.tool.OcrUtil ocrUtil;

    /**
     * 导出
     * @param response
     * @param params
     */

    @PostMapping("/IDCardOCR/export")
    public void IDCardOCRexport(HttpServletResponse response, Params params)
    {
        AjaxResult list1 = IDCardOCRList(params);
        List<IdCardResult> rows = JSONUtil.toList(JSONUtil.toJsonStr(list1.get("rows")), IdCardResult.class);
        ExcelUtil<IdCardResult> util = new ExcelUtil<IdCardResult>(IdCardResult.class);
        util.exportExcel(response, rows, "身份证资料");
    }
    @PostMapping("/BankCardOCR/export")
    public void BankCardOCRexport(HttpServletResponse response, Params params)
    {
        AjaxResult list1 = BankCardOCRList(params);
        List<BankCardOcr> rows = JSONUtil.toList(JSONUtil.toJsonStr(list1.get("rows")), BankCardOcr.class);
        ExcelUtil<BankCardOcr> util = new ExcelUtil<BankCardOcr>(BankCardOcr.class);
        util.exportExcel(response, rows, "银行卡资料");
    }
    @PostMapping("/BizLicenseOCR/export")
    public void BizLicenseOCRexport(HttpServletResponse response, Params params)
    {
        AjaxResult list1 = BizLicenseOCRList(params);
        List<BizLicenseOcr> rows = JSONUtil.toList(JSONUtil.toJsonStr(list1.get("rows")), BizLicenseOcr.class);
        ExcelUtil<BizLicenseOcr> util = new ExcelUtil<BizLicenseOcr>(BizLicenseOcr.class);
        util.exportExcel(response, rows, "企业资料");
    }

    /**
     * 通用图片识别 上传
     *
     * @param file
     * @return
     * @throws Exception
     */
   /* @PostMapping("/GeneralBasicOCR")
    public AjaxResult uploadGeneralBasicOCR(MultipartFile file) throws Exception {
        try {
            String SecretId = ocrUtil.getSecretId();
            String SecretKey = ocrUtil.getSecretKey();
            Credential cred = new Credential(SecretId, SecretKey);
            OcrClient client = new OcrClient(cred, "ap-beijing");
            String encode = Base64.encode(file.getBytes());
            GeneralBasicOCRRequest req = new GeneralBasicOCRRequest();
            req.setImageBase64(encode);
            // 返回的resp是一个GeneralBasicOCRResponse的实例，与请求对象对应
            GeneralBasicOCRResponse resp = client.GeneralBasicOCR(req);
            String vo = GeneralBasicOCRResponse.toJsonString(resp);

            GenralBasicOCRVO bean = JSONUtil.toBean(vo, GenralBasicOCRVO.class);

            // 输出json格式的字符串回包
            AjaxResult ajax = getUploadFile(file);
            ajax.put("GenralBasicOCRVO", bean);
            return ajax;
        } catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }
    }*/

    /** 营业执照列表
     * @Author WangFK
     * @Date 2024/12/16 0:10
     * @Param Params
     * @return
     **/
    @GetMapping("/BizLicenseOCR/list")
    public AjaxResult BizLicenseOCRList(Params params){
        Page<BizLicenseOcr> opeoplePage = new Page<BizLicenseOcr>(params.getPageNum(), params.getPageSize());
        LambdaQueryWrapper<BizLicenseOcr> lqw = new LambdaQueryWrapper<>();
        String search = params.getSearch();
        if (ObjectUtil.isNotEmpty(search)){
            lqw.like(BizLicenseOcr::getRegNum, search).or()
                    .like(BizLicenseOcr::getRegNum, search).or()
                    .like(BizLicenseOcr::getName, search);
        }
        opeoplePage = bizLicenseOcrService.page(opeoplePage, lqw);
        List<BizLicenseOcr> records = opeoplePage.getRecords();
        if (ObjectUtil.isEmpty(records)) {
            return AjaxResult.success("暂无信息");
        }
        return AjaxResult.success()
                .put("rows", records)
                .put("total", records.size());
    }
    /**
     * 通过主键查询单条数据
     *
     * @param id 主键
     * @return 单条数据
     */
    @GetMapping("/BizLicenseOCR/{id}")
    public AjaxResult selectBizLicenseOCROne(@PathVariable Serializable id) {
        return AjaxResult.success(bizLicenseOcrService.getById(id));
    }

    /**
     * 新增数据
     *
     * @param bizLicenseOcr 实体对象
     * @return 新增结果
     */
    @PostMapping("/BizLicenseOCR/save")
    public AjaxResult insertBizLicenseOCR(@RequestBody BizLicenseOcr bizLicenseOcr) {
        return AjaxResult.success(bizLicenseOcrService.save(bizLicenseOcr));
    }


    /**
     * 删除数据
     *
     * @param ids 主键结合
     * @return 删除结果
     */
    @DeleteMapping("/BizLicenseOCR/{ids}")
    public AjaxResult deleteBizLicenseOCR(@PathVariable String ids) {
        List<String> idList = StrUtil.split(ids, ",");
        return bizLicenseOcrService.removeByIds(idList) ? AjaxResult.success("删除成功") : AjaxResult.error("删除失败");
    }

    /**
     * 营业执照识别 上传
     *
     * @param file
     * @return
     * @throws Exception
     */
    @PostMapping("/BizLicenseOCR")
    public AjaxResult uploadBizLicenseOCR(MultipartFile file) throws Exception {
        try {
            SysUser sysUser = new SysUser();
            String SecretId = ocrUtil.getSecretId();
            String SecretKey = ocrUtil.getSecretKey();
            Credential cred = new Credential(SecretId, SecretKey);
            OcrClient client = new OcrClient(cred, "ap-beijing");
            String encode = Base64.encode(file.getBytes());
            // 返回的resp是一个IDCardOCRResponse的实例，与请求对象对应
            BizLicenseOCRRequest req = new BizLicenseOCRRequest();
            req.setImageBase64(encode);
            // 返回的resp是一个BizLicenseOCRResponse的实例，与请求对象对应
            BizLicenseOCRResponse resp = client.BizLicenseOCR(req);
            // 输出json格式的字符串回包
            AjaxResult ajax = getUploadFile(file);
            ajax.put("BizLicenseOCRVO", JSONUtil.toBean(BizLicenseOCRResponse.toJsonString(resp), BizLicenseOcr.class));
            return ajax;
        } catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }
    }

    /**
     * 银行卡识别 上传
     *
     * @param file
     * @return
     * @throws Exception
     */
    @PostMapping("/BankCardOCR")
    public AjaxResult uploadBankCardOCR(MultipartFile file) throws Exception {
        try {
            String SecretId = ocrUtil.getSecretId();
            String SecretKey = ocrUtil.getSecretKey();
            Credential cred = new Credential(SecretId, SecretKey);
            OcrClient client = new OcrClient(cred, "ap-beijing");
            String encode = Base64.encode(file.getBytes());
            // 返回的resp是一个IDCardOCRResponse的实例，与请求对象对应
            BankCardOCRRequest req = new BankCardOCRRequest();
            req.setImageBase64(encode);
            BankCardOCRResponse resp = client.BankCardOCR(req);
            // 输出json格式的字符串回包
            AjaxResult ajax = getUploadFile(file);
            ajax.put("BankCardOCRVO", JSONUtil.toBean(BankCardOCRResponse.toJsonString(resp), BankCardOcr.class));
            return ajax;
        } catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }
    }
    /** 银行卡列表
     * @Author WangFK
     * @Date 2024/12/16 0:10
     * @Param Params
     * @return
     **/
    @GetMapping("/BankCardOCR/list")
    public AjaxResult BankCardOCRList(Params params){
        Page<BankCardOcr> opeoplePage = new Page<BankCardOcr>(params.getPageNum(), params.getPageSize());
        LambdaQueryWrapper<BankCardOcr> lqw = new LambdaQueryWrapper<>();
        String search = params.getSearch();
        if (ObjectUtil.isNotEmpty(search)){
            lqw.like(BankCardOcr::getCardNo, search).or()
                    .like(BankCardOcr::getBankInfo, search);
        }
        opeoplePage = bankCardOcrService.page(opeoplePage, lqw);
        List<BankCardOcr> records = opeoplePage.getRecords();
        if (ObjectUtil.isEmpty(records)) {
            return AjaxResult.success("暂无信息");
        }
        return AjaxResult.success()
                .put("rows", records)
                .put("total", records.size());
    }
    /**
     * 通过主键查询单条数据
     *
     * @param id 主键
     * @return 单条数据
     */
    @GetMapping("/BankCardOCR/{id}")
    public AjaxResult selectBankCardOCROne(@PathVariable Serializable id) {
        return AjaxResult.success(bankCardOcrService.getById(id));
    }

    /**
     * 新增数据
     *
     * @param bizLicenseOcr 实体对象
     * @return 新增结果
     */
    @PostMapping("/BankCardOCR/save")
    public AjaxResult insert(@RequestBody BankCardOcr bizLicenseOcr) {
        return AjaxResult.success(bankCardOcrService.save(bizLicenseOcr));
    }


    /**
     * 删除数据
     *
     * @param ids 主键结合
     * @return 删除结果
     */
    @DeleteMapping("/BankCardOCR/{ids}")
    public AjaxResult delete(@PathVariable String ids) {
        List<String> idList = StrUtil.split(ids, ",");
        return bankCardOcrService.removeByIds(idList) ? AjaxResult.success("删除成功") : AjaxResult.error("删除失败");
    }
    /**
     * 身份证识别 并上传
     *
     * @param file
     * @return
     * @throws Exception
     */
    @PostMapping("/IDCardOCR")
    public AjaxResult uploadFileIDCardOCR(MultipartFile file) throws Exception {
        try {
            String SecretId = ocrUtil.getSecretId();
            String SecretKey = ocrUtil.getSecretKey();
            Credential cred = new Credential(SecretId, SecretKey);
            OcrClient client = new OcrClient(cred, "ap-beijing");
            IDCardOCRRequest req = new IDCardOCRRequest();
            String encode = Base64.encode(file.getBytes());
            req.setImageBase64(encode);
            req.setCardSide("FRONT");
            // 返回的resp是一个IDCardOCRResponse的实例，与请求对象对应
            IDCardOCRResponse resp = client.IDCardOCR(req);
            // 输出json格式的字符串回包
            IdCardResult vo = JSONUtil.toBean(IDCardOCRResponse.toJsonString(resp), IdCardResult.class);
            AjaxResult ajax = getUploadFile(file);
            ajax.put("IdCardResultVO", vo);
            return ajax;
        } catch (Exception e) {
            return AjaxResult.error(e.getMessage());
        }
    }
    /** 身份证列表
     * @Author WangFK
     * @Date 2024/12/16 0:10
     * @Param Params
     * @return
     **/
    @GetMapping("/IDCardOCR/list")
    public AjaxResult IDCardOCRList(Params params){
        Page<IdCardResult> opeoplePage = new Page<IdCardResult>(params.getPageNum(), params.getPageSize());
        LambdaQueryWrapper<IdCardResult> lqw = new LambdaQueryWrapper<>();
        String search = params.getSearch();
        if (ObjectUtil.isNotEmpty(search)){
            lqw.like(IdCardResult::getName, search).or()
                    .like(IdCardResult::getSex, search)
                    .like(IdCardResult::getBirth, search)
                    .like(IdCardResult::getAddress, search)
                    .like(IdCardResult::getIdNum, search);
        }
        opeoplePage = idCardResultService.page(opeoplePage, lqw);
        List<IdCardResult> records = opeoplePage.getRecords();
        if (ObjectUtil.isEmpty(records)) {
            return AjaxResult.success("暂无信息");
        }
        return AjaxResult.success()
                .put("rows", records)
                .put("total", records.size());
    }
    /**
     * 通过主键查询单条数据
     *
     * @param id 主键
     * @return 单条数据
     */
    @GetMapping("/IDCardOCR/{id}")
    public AjaxResult selectIDCardOCROne(@PathVariable Serializable id) {
        return AjaxResult.success(idCardResultService.getById(id));
    }

    /**
     * 新增数据
     *
     * @param bizLicenseOcr 实体对象
     * @return 新增结果
     */
    @PostMapping("/IDCardOCR/save")
    public AjaxResult insertIDCardOCR(@RequestBody IdCardResult bizLicenseOcr) {
        return AjaxResult.success(idCardResultService.save(bizLicenseOcr));
    }


    /**
     * 删除数据
     *
     * @param ids 主键结合
     * @return 删除结果
     */
    @DeleteMapping("/IDCardOCR/{ids}")
    public AjaxResult deleteIDCardOCR(@PathVariable String ids) {
        List<String> idList = StrUtil.split(ids, ",");
        return idCardResultService.removeByIds(idList) ? AjaxResult.success("删除成功") : AjaxResult.error("删除失败");
    }
    private AjaxResult getUploadFile(MultipartFile file) throws IOException {
        // 上传文件路径
        String filePath = RuoYiConfig.getUploadPath();
        // 上传并返回新文件名称
        String fileName = FileUploadUtils.upload(filePath, file);
        String url = serverConfig.getUrl() + fileName;
        AjaxResult ajax = AjaxResult.success();
        ajax.put("url", url);
        ajax.put("fileName", fileName);
        ajax.put("newFileName", FileUtils.getName(fileName));
        ajax.put("originalFilename", file.getOriginalFilename());

        return ajax;
    }


}

